home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1996 #1 / Amiga Plus CD - 1996 - No. 1.iso / pd / netz / xbtx_v1.1 / modemservice.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-26  |  7.8 KB  |  421 lines

  1. /*
  2. **    $Id: ModemService.cpp 1.4 1995/09/26 19:45:11 olsen Exp olsen $
  3. **
  4. **    :ts=4
  5. */
  6.  
  7. /*
  8.  * Copyright © 1995 by Olaf Barthel, All Rights Reserved
  9.  *
  10.  * Redistribution and use in source and binary forms, with or without
  11.  * modification, are permitted provided that the following conditions
  12.  * are met:
  13.  * 1. Redistributions of source code must retain the above copyright
  14.  *    notice, this list of conditions and the following disclaimer.
  15.  * 2. Redistributions in binary form must reproduce the above copyright
  16.  *    notice, this list of conditions and the following disclaimer in the
  17.  *    documentation and/or other materials provided with the distribution.
  18.  *
  19.  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
  20.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
  22.  * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  24.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  25.  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  26.  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  27.  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  28.  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29.  *
  30.  * This software has not been validated by the ``Bundesamt fuer Zulassungen in
  31.  * der Telekommunikation'' of the ``Deutsche Bundepost Telekom'' and thus
  32.  * must not be used for accessing the BTX-Network of the Telekom in Germany.
  33.  *
  34.  * Diese Software hat keine Zulassung durch das Bundesamt fuer Zulassungen in
  35.  * der Telekommunikation der Deutschen Bundespost Telekom und darf daher nicht
  36.  * am Netz der Deutschen Bundespost Telekom in Deutschland betrieben werden.
  37.  */
  38.  
  39. #include "ModemService.hpp"
  40.  
  41. #include <dos/dos.h>
  42.  
  43. #include <devices/timer.h>
  44.  
  45. #include <clib/exec_protos.h>
  46. #include <clib/dos_protos.h>
  47.  
  48. #ifdef __SASC
  49. #include <pragmas/exec_pragmas.h>
  50. #include <pragmas/dos_pragmas.h>
  51.  
  52. extern struct ExecBase        *SysBase;
  53. extern struct DosLibrary    *DOSBase;
  54. #endif    // _SASC
  55.  
  56. #include <string.h>
  57. #include <stdio.h>
  58.  
  59. ModemService::ModemService()
  60. {
  61.     AppChannel        = NULL;
  62.     Connected        = FALSE;
  63.  
  64.     HangupCommand    = NULL;
  65.  
  66.     Next            = -1;
  67.  
  68.     TimePort        = NULL;
  69.     TimeRequest        = NULL;
  70. }
  71.  
  72. ModemService::~ModemService()
  73. {
  74.     Close();
  75. }
  76.  
  77. LONG ModemService::Open(IOChannel *Channel,BTXDisplay *Display)
  78. {
  79.     if(TimePort = CreateMsgPort())
  80.     {
  81.         TimeMask = 1UL << TimePort->mp_SigBit;
  82.  
  83.         if(TimeRequest = (struct timerequest *)CreateIORequest(TimePort,sizeof(timerequest)))
  84.         {
  85.             if(OpenDevice((UBYTE *)TIMERNAME,UNIT_VBLANK,(struct IORequest *)TimeRequest,NULL))
  86.             {
  87.                 DeleteIORequest((struct IORequest *)TimeRequest);
  88.                 TimeRequest = NULL;
  89.             }
  90.         }
  91.     }
  92.  
  93.     if(TimeRequest)
  94.     {
  95.         AppChannel = Channel;
  96.         AppDisplay = Display;
  97.  
  98.         return(0);
  99.     }
  100.  
  101.     Close();
  102.  
  103.     return(-1);
  104. }
  105.  
  106. VOID ModemService::Close(VOID)
  107. {
  108.     if(Connected)
  109.         Disconnect();
  110.  
  111.     if(TimeRequest)
  112.     {
  113.         CloseDevice((struct IORequest *)TimeRequest);
  114.  
  115.         DeleteIORequest((struct IORequest *)TimeRequest);
  116.         TimeRequest = NULL;
  117.     }
  118.  
  119.     if(TimePort)
  120.     {
  121.         DeleteMsgPort(TimePort);
  122.         TimePort = NULL;
  123.     }
  124.  
  125.     if(HangupCommand)
  126.     {
  127.         delete HangupCommand;
  128.         HangupCommand = NULL;
  129.     }
  130.  
  131.     AppChannel = NULL;
  132. }
  133.  
  134. LONG ModemService::Connect(CONST STRPTR Init,CONST STRPTR Dial,CONST STRPTR Number,CONST STRPTR Hangup)
  135. {
  136.     STATIC STRPTR ResponseTable[] =
  137.     {
  138.         "OK",
  139.         "NO CARRIER",
  140.         "ERROR",
  141.         "BUSY",
  142.         "NO DIALTONE",
  143.         "CONNECT",
  144.         "NO ANSWER",
  145.         "RINGING",
  146.         "RING",
  147.  
  148.         NULL
  149.     };
  150.  
  151.     UBYTE    Buffer[40];
  152.     LONG    Result,i;
  153.     ULONG    Signals;
  154.  
  155.     AppDisplay->PutLine(NULL);
  156.  
  157.     if(!HangupCommand)
  158.     {
  159.         if(HangupCommand = new char[strlen(Hangup) + 1])
  160.             strcpy(HangupCommand,Hangup);
  161.     }
  162.  
  163.     if(Init[0])
  164.     {
  165.         BOOL Done = FALSE;
  166.  
  167.         SendCommand(Init);
  168.  
  169.         if((Result = GetLine((char *)&Buffer[0],40)) != -1)
  170.         {
  171.             AppDisplay->PutLine((STRPTR)Buffer);
  172.  
  173.             Result = GetLine((char *)&Buffer[0],40);
  174.         }
  175.  
  176.         do
  177.         {
  178.             if(Result < 0)
  179.             {
  180.                 AppDisplay->PutLine("Timeout while initializing modem");
  181.  
  182.                 return(MODEM_Timeout);
  183.             }
  184.  
  185.             AppDisplay->PutLine((STRPTR)Buffer);
  186.  
  187.             for(i = 0 ; ResponseTable[i] ; i++)
  188.             {
  189.                 if(strstr((char *)Buffer,ResponseTable[i]))
  190.                 {
  191.                     if(i == MODEM_Ok)
  192.                         Done = TRUE;
  193.                     else
  194.                     {
  195.                         AppDisplay->PutLine("Error while initializing modem");
  196.  
  197.                         return(i);
  198.                     }
  199.                 }
  200.             }
  201.  
  202.             if(!Done)
  203.                 Result = GetLine((char *)&Buffer[0],40);
  204.         }
  205.         while(!Done);
  206.     }
  207.  
  208.     SendCommand(Dial);
  209.     SendCommand(Number);
  210.     SendCommand("^M");
  211.  
  212.     if(GetLine((char *)&Buffer[0],40) != -1)
  213.         AppDisplay->PutLine((STRPTR)Buffer);
  214.  
  215.     TimeRequest->tr_node.io_Command    = TR_ADDREQUEST;
  216.     TimeRequest->tr_time.tv_secs    = 90;
  217.     TimeRequest->tr_time.tv_micro    = 0;
  218.  
  219.     SetSignal(0,TimeMask);
  220.  
  221.     SendIO((struct IORequest *)TimeRequest);
  222.  
  223.     Signals = NULL;
  224.  
  225.     for(;;)
  226.     {
  227.         Signals = Wait(AppChannel->WaitMask() | AppDisplay->WaitMask() | TimeMask | SIGBREAKF_CTRL_C);
  228.  
  229.         if((Signals & (AppChannel->WaitMask() | AppDisplay->WaitMask() | TimeMask)) == TimeMask)
  230.         {
  231.             AppDisplay->PutLine("Timeout");
  232.  
  233.             WaitIO((struct IORequest *)TimeRequest);
  234.  
  235.             SendCommand("^M");
  236.  
  237.             return(MODEM_Timeout);
  238.         }
  239.  
  240.         if(Signals & SIGBREAKF_CTRL_C)
  241.         {
  242.             AppDisplay->PutLine("Aborted");
  243.  
  244.             if(!CheckIO((struct IORequest *)TimeRequest))
  245.                 AbortIO((struct IORequest *)TimeRequest);
  246.  
  247.             WaitIO((struct IORequest *)TimeRequest);
  248.  
  249.             SendCommand("^M");
  250.  
  251.             return(MODEM_NoCarrier);
  252.         }
  253.  
  254.         if(Signals & AppDisplay->WaitMask())
  255.         {
  256.             LONG Result = AppDisplay->GetChar();
  257.  
  258.             if(Result == '\033' || Result == ('C' & 0x1F))
  259.             {
  260.                 AppDisplay->PutLine("Aborted");
  261.  
  262.                 if(!CheckIO((struct IORequest *)TimeRequest))
  263.                     AbortIO((struct IORequest *)TimeRequest);
  264.  
  265.                 WaitIO((struct IORequest *)TimeRequest);
  266.  
  267.                 SendCommand("^M");
  268.  
  269.                 return(MODEM_NoCarrier);
  270.             }
  271.         }
  272.  
  273.         if(Signals & AppChannel->WaitMask())
  274.         {
  275.             Result = GetLine((char *)&Buffer[0],40);
  276.  
  277.             if(Result < 0)
  278.             {
  279.                 if(!CheckIO((struct IORequest *)TimeRequest))
  280.                     AbortIO((struct IORequest *)TimeRequest);
  281.  
  282.                 WaitIO((struct IORequest *)TimeRequest);
  283.  
  284.                 return(MODEM_Timeout);
  285.             }
  286.  
  287.             AppDisplay->PutLine((STRPTR)Buffer);
  288.  
  289.             for(i = 0 ; ResponseTable[i] ; i++)
  290.             {
  291.                 if(strstr((char *)Buffer,ResponseTable[i]))
  292.                 {
  293.                     AppChannel->Flush();
  294.  
  295.                     if(!CheckIO((struct IORequest *)TimeRequest))
  296.                         AbortIO((struct IORequest *)TimeRequest);
  297.  
  298.                     WaitIO((struct IORequest *)TimeRequest);
  299.  
  300.                     if(i == MODEM_Connect)
  301.                         Connected = TRUE;
  302.  
  303.                     if(i != MODEM_Ringing && i != MODEM_Ring)
  304.                         return(i);
  305.                     else
  306.                         break;
  307.                 }
  308.             }
  309.         }
  310.     }
  311. }
  312.  
  313. VOID ModemService::Disconnect(VOID)
  314. {
  315.     if(Connected)
  316.     {
  317.         if(HangupCommand)
  318.             SendCommand(HangupCommand);
  319.  
  320.         Connected = FALSE;
  321.     }
  322.  
  323.     if(HangupCommand)
  324.     {
  325.         delete HangupCommand;
  326.         HangupCommand = NULL;
  327.     }
  328. }
  329.  
  330. LONG ModemService::GetLine(STRPTR Buffer,LONG Size)
  331. {
  332.     LONG Len = 0,Result;
  333.  
  334.     for(;;)
  335.     {
  336.         Result = AppChannel->GetCharDirect(4);
  337.  
  338.         if(Result < 0)
  339.             return(Result);
  340.         else
  341.         {
  342.             if(Result == '\n' || (!Len && Result == ' '))
  343.                 continue;
  344.  
  345.             if(Result == '\r')
  346.             {
  347.                 Buffer[Len] = 0;
  348.  
  349.                 return(Len);
  350.             }
  351.  
  352.             if(Result < ' ')
  353.             {
  354.                 Result += ' ';
  355.  
  356.                 Buffer[Len++] = '^';
  357.  
  358.                 if(Len == Size - 1)
  359.                 {
  360.                     Buffer[Len] = 0;
  361.  
  362.                     return(Len);
  363.                 }
  364.             }
  365.  
  366.             Buffer[Len++] = (char)Result;
  367.  
  368.             if(Len == Size - 1)
  369.             {
  370.                 Buffer[Len] = 0;
  371.  
  372.                 return(Len);
  373.             }
  374.         }
  375.     }
  376. }
  377.  
  378. VOID ModemService::SendCommand(CONST STRPTR Command)
  379. {
  380.     BOOL Escape;
  381.     WORD i;
  382.     char c;
  383.  
  384.     for(i = 0, Escape = FALSE ; i < strlen(Command) ; i++)
  385.     {
  386.         switch(Command[i])
  387.         {
  388.             case '^':
  389.  
  390.                 if(Escape)
  391.                     AppChannel->PutCharDirect('^');
  392.  
  393.                 Escape ^= TRUE;
  394.                 break;
  395.  
  396.             case '~':
  397.  
  398.                 if(Escape)
  399.                     AppChannel->PutCharDirect('~');
  400.                 else
  401.                     Delay(TICKS_PER_SECOND);
  402.  
  403.                 break;
  404.  
  405.             default:
  406.  
  407.                 if(Escape)
  408.                 {
  409.                     c = (char)(Command[i] & 0x1F);
  410.  
  411.                     Escape = FALSE;
  412.                 }
  413.                 else
  414.                     c = Command[i];
  415.  
  416.                 AppChannel->PutCharDirect(c);
  417.                 break;
  418.         }
  419.     }
  420. }
  421.